<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>路由守卫</title>
    <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
    <h1>Hello App</h1>
    <p>
        <router-link to="/foo/1">Go to Foo 1</router-link>
        <router-link to="/foo/2">Go to Foo 2</router-link>
        <router-link to="/foo/1/profile">Go to Foo child</router-link>
        <router-link to="/bar">Go to bar</router-link>
    </p>

    <router-view></router-view>
</div>

<script>
    const Foo = {
        template: '<div> <h2>Foo- {{ $route.params.id }}</h2><router-view></router-view></div>',
        watch: {
            '$route'(to, from) {
                console.log('watch---', to, from);
            }
        },

        //组件内前置守卫  导航触发时
        beforeRouteEnter(to, from, next) {
            // console.log('beforeRouteEnter---to-', to)
            // console.log('beforeRouteEnter---from-', from)
            // console.log('beforeRouteEnter---next-', next)

            // 在渲染该组件的对应路由被 confirm 前调用
            // 不！能！获取组件实例 `this`
            // 因为当守卫执行前，组件实例还没被创建
            // 可以传一个回调给next, 【切只有这个守卫接收回调】
            next(function (vm) {
                console.log("params  --->  ", vm.$route.params.id);
            })
        },
        //v2.2+
        //组件内前置守卫  路由改变，但是该组件被复用时调用
        beforeRouteUpdate(to, from, next) {
            // console.log('beforeRouteUpdate ---to-', to)
            // console.log('beforeRouteUpdate ---from-', from)
            // console.log('beforeRouteUpdate ---next-', next)

            //*********************************************************************************
            // 在当前路由改变，但是该组件被复用时调用
            // 举例来说，对于一个带有动态参数的路径 /foo/:id，在 /foo/1 和 /foo/2 之间跳转的时候，
            // 由于会渲染同样的 Foo 组件，因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
            // 可以访问组件实例 `this`
            //    这里要注意，/foo/1 和 /foo/1/profile
            //    都是调用一个组件，vue在相同组件重复使用时给予缓存，所以在组件发生变化是必须要触发next()方法
            //
            //*********************************************************************************
            next()
        },

        //组件内前置守卫  导航离开
        //这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消
        beforeRouteLeave(to, from, next) {
            // console.log('beforeRouteLeave---to-', to)
            // console.log('beforeRouteLeave---from-', from)
            // console.log('beforeRouteLeave---next-', next)

            // 导航离开该组件的对应路由时调用
            // 可以访问组件实例 `this`

            next()
        }
    }
    const Bar = {
        template: '<div>bar</div>',
        beforeRouteLeave (to, from , next) {
            const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
            if (answer) {
                next()
            } else {
                next(false)
            }
        }
    }
    const Profile = {template: '<div>my name is profile</div>'};


    const routes = [{
        path: '/foo/:id', component: Foo,
        children: [{
            // 当 /foo/:id/profile 匹配成功，
            // FooProfile 会被渲染在 Foo 的 <router-view> 中

            path: 'profile',
            component: Profile
        }, {
            // 默认视图

            path: '',
            component: {template: '<div>there is default view</div>'}
        }
        ]
    },
        {path: '/bar', component: Bar}
    ]

    const router = new VueRouter({
        routes
    });

    //全局前置钩子
    router.beforeEach((to, from, next) => {
        console.log('beforeEach-', to)
        console.log('beforeEach---from-', from)
        console.log('beforeEach---next-', next)

        next()
    });

    //v2.5+
    //在导航被确认之前，同时在所有组件内守卫和异步路由组件被解析之后，解析守卫就被调用
    router.beforeResolve((to, from, next) => {
        console.log('beforeResolve-', to)
        console.log('beforeResolve---from-', from)
        console.log('beforeResolve---next-', next)

        next()
    });

    //全局后置钩子
    router.afterEach((to, from) => {
        console.log('afterEach-', to)
        console.log('afterEach---from-', from)
    });

    const app = new Vue({
        router
    }).$mount("#app");
</script>
</body>
</html>
